﻿namespace GameLib.Games.Components
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using GameLib.Games.Util;

    public class ModDependencyHandler<T> : AbstractModMatcherHandler<T> where T : IMod
    {
        public override ModMatcherHandlerAction HandleList(IList<MatcherStruct<T>> list)
        {
            if (list.Count > 0)
            {
                ModMatcherHandlerAction result = ModMatcherHandlerAction.DoNothing;
                foreach (MatcherStruct<T> matcherStruct in list)
                {
                    if ((!matcherStruct.Matcher.Owner.IsActive) || (matcherStruct.Match.IsActive))
                    {
                        break;
                    }

                    ModMatcherHandlerAction matcherResult = Handle(matcherStruct.Matcher, matcherStruct.Match);
                    if (matcherResult.Equals(ModMatcherHandlerAction.DisableMod) || matcherResult.Equals(ModMatcherHandlerAction.EnableMatchingMod)) {
                        break;
                    }
                }

                return result;
            }
            else
            {
                return ModMatcherHandlerAction.DoNothing;
            }
        }

        public override ModMatcherHandlerAction Handle(IModMatcher matcher, T mod)
        {
            ModMatcherHandlerEventArgs eventArgs = new ModMatcherHandlerEventArgs(mod);

            OnBeforeHandleEvent(eventArgs);

            if (eventArgs.Action == null)
            {
                switch (this.displayMessage(matcher, mod))
                {
                    case DialogResult.Yes:
                        eventArgs.Action = ModMatcherHandlerAction.EnableMatchingMod;
                        break;
                    case DialogResult.No:
                        eventArgs.Action = ModMatcherHandlerAction.DisableMod;
                        break;
                    default:
                        eventArgs.Action = ModMatcherHandlerAction.DoNothing;
                        break;
                }
            }

            if (eventArgs.Handle)
            {
                switch (eventArgs.Action)
                {
                    case ModMatcherHandlerAction.EnableMatchingMod:
                        mod.Owner.DisableMod(mod);
                        break;
                    case ModMatcherHandlerAction.DisableMod:
                        matcher.Owner.Owner.DisableMod(matcher.Owner);
                        break;
                }
                eventArgs.Handled = true;
            }

            OnAfterHandleEvent(eventArgs);

            return eventArgs.Action;
        }

        private DialogResult displayMessage(IModMatcher matcher, T mod)
        {
            string message = matcher.Owner.Name + " is missing a dependant mod. The mod titled " + mod.Name + "(" + mod.Id + ") satisfies this dependency and was found on your computer.";
            if (!string.IsNullOrEmpty(matcher.Message))
            {
                message += "\n\nDetails:\n" + matcher.Message;
            }

            message += "\n\nIf you do not satisfy the missing dependency, you will likely encounter errors or crashes within the game. If you cannot enable the dependency, you should disable the dependent mod.";

            message += "\n\nWould you like to enable " + mod.Name + " to satisfy the dependency?\n";
            message += "\n    Press Yes to enable " + mod.Name;
            message += "\n    Press No to disable " + matcher.Owner.Name;
            message += "\n    Press Cancel to leave the dependency unmet, ignoring this warning.";

            string title = matcher.Owner.Name + " - Missing Dependency";

            return MessageBox.Show(message, title, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
        }
    }
}
